#ifndef BIGBLOCK_H
#define BIGBLOCK_H

#include <SmallBlock.h>
#include <iostream>
#include "PartitionElement.h"

class BigBlock
{
public:
    //Main Constructor
    BigBlock( SmallBlock* blocks[] );

    //Get small block with select coords
    SmallBlock* getSmallBlock( int currX, int currY ) ;
    //Get digit with select coords
    short getElement( int currX, int currY ) ;
    //Get Cell pointer
    Cell* getCell( int currX, int currY ) ;


    //Check rules in sudoku
    bool checkRules() ;

    bool allIsFilled() ;
    bool assumptionsIs() ;


    //Get X coord of block
    int getX() ;
    //Get Y coord of block
    int getY() ;
    //Print Big Block
    friend std::ostream& operator<<( std::ostream& out, BigBlock block ) ;
    std::ostream& print( std::ostream& out ) ;
    //Get filled cells
    int getBusyElements() ;


//-----Functions for resolve sudoku------
public:
    //--Make the assumption about all digits in block--
    int makeTheAssumption() ;
protected:
    //Exclude digit which already exist in block 3x3
    int findInBlock() ;
    //Exclude digit which already exist in row
    int findInRow() ;
    //Exclude digit which already exist in column
    int findInColumn() ;
    //If exist two equals couple exclude this digit from other cells
    //If exist in row, exclude from row etc.
    int findStealthTwo() ;
    int findLockedDigit() ; //To delete
    int findLockedDigit2() ;
    int findXWing() ;


public:
    //--Get partition element base on assumption--
    PartitionElement *getPartitionElement() ;
protected:
    //If in assumption only one digit, set is as value
    PartitionElement* findSingles() ;
    //If digit exist in only one assumption, set it as value
    PartitionElement* findStealthSingles() ;


    /*
    PartitionElement* findStealthThree() ;
    //int findStealthFour() ;
    PartitionElement* findBareTwo() ;
    PartitionElement* findBareThree() ;
    //int findBareFour() ;

    PartitionElement* findXWing() ;
    */
    //...

private:
    //Matrix for small block
    SmallBlock* matrix[3][3] ;
    //X coord of big block
    int x ;
    //Y coord of big block
    int y ;
};

#endif // BIGBLOCK_H
